import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:get/get.dart';
import 'package:mziot/app/data/device_group_entity.dart';
import 'package:mziot/app/data/device_list_entity.dart';
import 'package:mziot/app/data/group_down_entity.dart';
import 'package:mziot/app/data/scene_list_entity.dart';
import 'package:mziot/app/modules/devices/device_provider.dart';
import 'package:mziot/app/modules/devices/views/chose_scene_view.dart';
import 'package:mziot/app/modules/scene/scene_provider.dart';
import 'package:mziot/app/routes/app_pages.dart';
import 'package:mziot/app/tools/blue_service.dart';
import 'package:mziot/app/tools/tools.dart';
import 'package:mziot/generated/locales.g.dart';

class DeviceManagerController extends GetxController {
  DeviceProvider provider = DeviceProvider();
  SceneProvider sceneProvider = SceneProvider();

  final isSelected = false.obs;
  DeviceListList? deviceInfo;
  DeviceGroupList? groupInfo;
  final productImage = ''.obs;
  //是否是添加设备
  var isAdd = false;
  var isGroup = false;
  int? selectedGroupId;
  DiscoveredDevice? bluetoothDevice;
  String? meshKey;
  final infoName = ''.obs;
  List<int>? sceneIds;
  List<int>? deviceIds;
  List<GroupDownEntity>? groupList;
  Timer? _timer;
  final isLoading = false.obs;
  final selectText = ''.obs;
  final deviceText = ''.obs;
  List<SceneListEntity> sceneList = [];
  List<DeviceListList> deviceList = [];
  final isNetDevice = false.obs;
  var isSend = false;

  @override
  void onInit() {
    super.onInit();

    final params = Get.arguments as Map;
    isGroup = params['group'] as bool;
    isAdd = params['add'] as bool;
    if (!isGroup && isAdd) {
      bluetoothDevice = params['device'] as DiscoveredDevice;
    }
    if (bluetoothDevice != null) {
      infoName.value = bluetoothDevice?.name ?? '';
    }
    if (params['name'] is String) {
      infoName.value = params['name'] as String;
    }

    if (params['data'] != null) {
      if (isGroup) {
        groupInfo = params['data'];
        infoName.value = groupInfo?.groupName ?? '';
        fetchGroupInfo();
      } else {
        deviceInfo = params['data'];
        infoName.value = deviceInfo?.deviceName ?? '';
        fetchDeviceInfo();
      }
    }
  }

  @override
  void onReady() async {
    super.onReady();

    if (bluetoothDevice != null) {
      fetchMesh();
      fetchPic(bluetoothDevice?.name ?? '');
      Future.delayed(Duration(seconds: 1), () {
        BlueService.share.connectDevice(bluetoothDevice);
      });
    }
  }

  void fetchMesh() {
    provider.takeMesh().then((value) {
      if (value?.isSuccess ?? false) {
        logger.v('mesh ${value?.data}');
        meshKey = value!.data;
      }
    });
  }

  void fetchGroupList() {
    provider.takeGroupDownList().then((value) {
      if (value?.isSuccess ?? false) {
        groupList = value?.data ?? [];
        if (groupList!.isNotEmpty) {
          openChooseAction(false);
        } else {
          showToast(LocaleKeys.tips_empty.tr);
        }
      } else {
        showToast(value?.msg ?? LocaleKeys.tips_empty.tr);
      }
    });
  }

  void fetchAddDevice() async {
    if (isLoading.value) {
      return;
    }
    isLoading.value = true;
    EasyLoading.show(status: LocaleKeys.add_devices_device_init.tr);
    final enable = await MPermission.instance.bluetooth();
    if (!enable) {
      isLoading.value = false;
      EasyLoading.dismiss();
      return;
    }
    if (BlueService.share.deviceState != DeviceConnectionState.connected) {
      await BlueService.share.connectDevice(bluetoothDevice);
      isLoading.value = false;
      EasyLoading.dismiss();
      return;
    }
    EasyLoading.show(status: LocaleKeys.add_devices_device_init.tr);
    debugPrint('addDevice ...');
    provider
        .addDevice(infoName.value, bluetoothDevice?.name ?? '', selectedGroupId, null)
        .then((value) {
      if (value?.isSuccess ?? false) {
        final need = value?.data?.isConfigNet ?? false;
        Future.delayed(Duration(seconds: 1), () {
          localAction(need, value?.data?.id ?? 0, value?.data?.command);
        });
      } else {
        isLoading.value = false;
        EasyLoading.dismiss();
      }
      if (!(value?.isSuccess ?? false)) {
        showToast(value!.msg!);
      }
    }).catchError((_) {
      isLoading.value = false;
      EasyLoading.dismiss();
    });
  }

  void fetchEditDevice() {
    if (isLoading.value) {
      return;
    }
    EasyLoading.show();
    isLoading.value = true;
    provider.editDevice(deviceInfo!.id!, infoName.value, selectedGroupId).then((value) {
      if (value?.isSuccess ?? false) {
        Future.delayed(Duration(seconds: 1), () {
          Get.back(result: true);
        });
        BlueService.share.execCmds(value?.data);
      }
      if (value?.msg != null) {
        showToast(value!.msg!);
      }
    }).whenComplete(() {
      isLoading.value = false;
      EasyLoading.dismiss();
    });
  }

  void fetchAddGroup() {
    if (isLoading.value) {
      return;
    }

    if (infoName.value.isEmpty || infoName.value == LocaleKeys.add_devices_group_title.tr) {
      return;
    }
    EasyLoading.show();
    isLoading.value = true;
    provider.editGroup(groupInfo?.id, infoName.value, sceneIds, deviceIds).then((value) {
      if (value?.isSuccess ?? false) {
        BlueService.share.execCmds(value?.data);
      }
      if (value?.msg != null) {
        showToast(value!.msg!);
      }
    }).whenComplete(() {
      Future.delayed(Duration(seconds: 1), () {
        isLoading.value = false;
        Get.back(result: true);
      });
      EasyLoading.dismiss();
    });
  }

  void fetchPic(String name) {
    provider.takePic(name).then((value) {
      if (value.isSuccess) {
        productImage.value = value.data?.productImg ?? '';
      }
    });
  }

  void fetchDeviceInfo() {
    provider.takeDeviceInfo(deviceInfo!.id!).then((value) {
      if (value.isSuccess) {
        infoName.value = value.data?.deviceName ?? '';
        selectedGroupId = value.data?.groupId;
        selectText.value = value.data?.groupName ?? '';
        productImage.value = value.data?.deviceImg ?? '';
        isNetDevice.value = value.data?.isNetDevice ?? false;
      }
    });
  }

  void fetchGroupInfo() {
    provider.takeGroupInfo(groupInfo!.id!).then((value) {
      if (value.isSuccess) {
        infoName.value = value.data?.groupName ?? '';
        sceneIds = value.data?.sceneIds;
        deviceIds = value.data?.deviceIds;
        selectText.value = value.data?.sceneName ?? '';
        deviceText.value = value.data?.deviceName ?? '';
      }
    });
  }

  void fetchSceneList() {
    sceneProvider.takeSceneList().then((value) {
      if (value.isSuccess) {
        sceneList = value.data ?? [];
        if (sceneList.isNotEmpty) {
          openChooseAction(false);
        } else {
          showToast(LocaleKeys.tips_empty.tr);
        }
      }
    });
  }

  void fetchDeviceList() {
    provider.deviceList().then((value) {
      if (value.isSuccess) {
        deviceList = value.data ?? [];

        if (deviceList.isNotEmpty) {
          openChooseAction(true);
        } else {
          showToast(LocaleKeys.tips_empty.tr);
        }
      }
    });
  }

  void openChooseAction(bool chooseDevice) {
    if (groupList?.isEmpty ?? true && !isGroup) {
      fetchGroupList();
      return;
    } else if (sceneList.isEmpty && isGroup && !chooseDevice) {
      fetchSceneList();
      return;
    } else if (deviceList.isEmpty && isGroup && chooseDevice) {
      fetchDeviceList();
      return;
    }

    if (isGroup && !chooseDevice) {
      sceneList = sceneList.map((e) {
        sceneIds?.forEach((element) {
          if (element == e.sceneId) {
            e.isSelected.value = true;
          }
        });
        return e;
      }).toList();
    } else if (isGroup && chooseDevice) {
      deviceList = deviceList.map((e) {
        deviceIds?.forEach((element) {
          if (element == e.deviceId) {
            e.isSelected.value = true;
          }
        });
        return e;
      }).toList();
    } else {
      groupList = groupList?.map((e) {
        if (e.id == selectedGroupId) {
          e.isSelected.value = true;
        }
        return e;
      }).toList();
    }
    Get.dialog(
      ChoseSceneView(
        isGroup,
        isGroup ? [] : groupList,
        isGroup
            ? !chooseDevice
                ? sceneList
                : []
            : [],
        chooseDevice ? deviceList : [],
        (value) {
          if (value is GroupDownEntity) {
            selectText.value = value.groupName ?? '';
            selectedGroupId = value.id;
          } else if (value is List<SceneListEntity>) {
            sceneIds = value.map((e) => e.sceneId!).toList();
            selectText.value = value.map((e) => e.sceneName!).toList().join(',');
          } else if (value is List<DeviceListList>) {
            deviceIds = value.map((e) => e.deviceId!).toList();
            deviceText.value = value.map((e) => e.deviceName!).toList().join(',');
          } else {
            selectText.value = '';
            sceneIds = [];
            selectedGroupId = null;
          }
        },
        isMutile: isGroup ? true : false,
      ),
      useSafeArea: false,
    );
  }

  void localAction(bool need, int id, dynamic cmds) async {
    if (_timer != null) {
      EasyLoading.dismiss();
      isLoading.value = false;
      return;
    }
    final enable = await MPermission.instance.bluetooth();
    if (!enable) {
      isLoading.value = false;
      EasyLoading.dismiss();
      return;
    }

    var count = 0;
    _timer = Timer.periodic(Duration(seconds: 5), (_) async {
      final deviceId = bluetoothDevice?.name.split('_').last;
      if (BlueService.share.deviceState == DeviceConnectionState.disconnected) {
        BlueService.share.connectDevice(bluetoothDevice);
      }

      final info = BlueService.share.deviceInfo(deviceId);
      if (!isSend && BlueService.share.writeCharacteristic != null) {
        try {
          await BlueService.share.execCmds(cmds);
          BlueService.share.localCmd(deviceId ?? '', meshKey);
          isSend = true;
        } catch (e) {
          Future.delayed(Duration(seconds: 5), () async {
            await BlueService.share.execCmds(cmds);
            BlueService.share.localCmd(deviceId ?? '', meshKey);
            isSend = true;
          });
        }
      }
      count++;
      if (count == 10) {
        showToast(LocaleKeys.tips_time_out.tr);
        timerStop();
        isSend = false;
        return;
      }

      if (info?.local == 1) {
        BlueService.share.isAdd = false;
        timerStop();
        showToast(LocaleKeys.add_devices_success.tr);
        Future.delayed(Duration(milliseconds: 1500), (){
          if (need) {
            Get.offNamed(Routes.WIFI, arguments: bluetoothDevice, parameters: {'id': id.toString()});
          } else {
            Get.back(result: 0);
          }
        });
      }
    });
  }

  void timerStop() {
    _timer?.cancel();
    _timer = null;
    isLoading.value = false;
    EasyLoading.dismiss();
  }

  @override
  void onClose() async {
    _timer?.cancel();
    _timer = null;
    EasyLoading.dismiss();
    if (bluetoothDevice != null) {
      BlueService.share.disConnectDevice();
    }
  }
}
